﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace GraphicsEditor
{
    public partial class RotateForm : Form
    {
        public RotateForm()
        {
            InitializeComponent();
        }

        ImageForm imf;

        public RotateForm(ImageForm imf)
        {
            this.imf = imf;
            InitializeComponent();

            Bitmap myBitmap = imf.GetBitmap();
            lblInformation.Text = ("The image is " + myBitmap.Width.ToString() + " wide and " + myBitmap.Height.ToString() + " tall.");
            txtWidth.Text = (myBitmap.Width / 2).ToString();
            txtHeight.Text = (myBitmap.Height / 2).ToString();
        }



        private void btnClockwiseRotation_Click(object sender, EventArgs e)
        {
            Bitmap currentImage = imf.GetBitmap();
            imf.undo();
            if (radioBtn90.Checked == true)
            {
                
                Rotate.Rotate90(currentImage);
            }
            else if (radioBtn180.Checked == true)
            {
                currentImage.RotateFlip(RotateFlipType.Rotate180FlipNone);
            }
            else if (radioBtn270.Checked == true)
            {
                currentImage.RotateFlip(RotateFlipType.Rotate270FlipNone);
            }
            imf.SetBitmap(currentImage);
        }

        private void btnFlip_Click(object sender, EventArgs e)
        {
            if (radioBtnHorizontalFlip.Checked == true)
            {
                imf.undo();
                Bitmap currentImage = imf.GetBitmap();
                currentImage.RotateFlip(RotateFlipType.RotateNoneFlipX);
                imf.SetBitmap(currentImage);
            }
            if (radioBtnVerticalFlip.Checked == true)
            {
                imf.undo();
                Bitmap currentImage = imf.GetBitmap();
                currentImage.RotateFlip(RotateFlipType.RotateNoneFlipY);
                imf.SetBitmap(currentImage);
            }
            if (radioBtnBoth.Checked == true)
            {
                imf.undo();
                Bitmap currentImage = imf.GetBitmap();
                currentImage.RotateFlip(RotateFlipType.RotateNoneFlipXY);
                imf.SetBitmap(currentImage);
            }

        }

        private void btnRotateandFlip_Click(object sender, EventArgs e)
        {
            btnFlip.PerformClick();
            btnClockwiseRotation.PerformClick();
        }

        private void btnFreeRotate_Click(object sender, EventArgs e)
        {
            Bitmap finalBitmap = imf.GetBitmap();
            float rotate90 = float.Parse(txtFreeDegreeRotation.Text);
            rotate90 = rotate90 % 360;
            if (rotate90 < 360)
                rotate90 += 360;
            while (rotate90 >= 90)
            {
                Rotate.Rotate90(finalBitmap);
                rotate90 -= 90;
            }
            float rotate = rotate90 * (float)(Math.PI / 180);//float.Parse(txtFreeDegreeRotation.Text) * (float)(Math.PI/180);
            float cos = (float)Math.Cos(rotate);
            float sin = (float)Math.Sin(rotate);
            int width = finalBitmap.Width;//imf.GetBitmap().Width;
            int height = finalBitmap.Height;//imf.GetBitmap().Height;

            int newWidth = Math.Abs((int)(sin * height + cos * width));
            int newHeight = Math.Abs((int)(cos * height + sin * width));
            int drawOriginX = (int)(sin * height);
            int drawOriginY = (int)(cos * height);
            
            Console.WriteLine("Width = " + newWidth + " Height = " + newHeight + " X= " + drawOriginX + " Y= " + drawOriginY);
            
            imf.undo();
            Bitmap rotatedImage = new Bitmap((int)newWidth,(int)newHeight );
            Graphics g = Graphics.FromImage(rotatedImage);
            float theta = rotate;
            Point []points;

            float oppositeBottom = sin * height;
            float oppositeTop = sin * width;
            float adjacentBottom = cos * height;
            float adjacentTop = cos * width;
            const double pi2 = Math.PI / 2.0;

            if (theta >= 0.0 && theta < pi2)
            {
                points = new Point[] 
                { 
                    new Point( (int) oppositeBottom, 0 ), 
                    new Point( newWidth, (int) oppositeTop ),
                    new Point( 0, (int) adjacentBottom )
                };
            }
            else if (theta >= pi2 && theta < Math.PI)
            {
                points = new Point[] 
                { 
                    new Point( newWidth, (int) oppositeTop ),
                    new Point( (int) adjacentTop, newHeight ),
                    new Point( (int) oppositeBottom, 0 )						 
                };
            }
            else if (theta >= Math.PI && theta < (Math.PI + pi2))
            {
                points = new Point[] 
                { 
                    new Point( (int) adjacentTop, newHeight ), 
                    new Point( 0, (int) adjacentBottom ),
                    new Point( newWidth, (int) oppositeTop )
                };
            }
            else // theta >= (Math.PI + pi2)
            {
                points = new Point[] 
                { 
                    new Point( 0, (int) adjacentBottom ), 
                    new Point( (int) oppositeBottom, 0 ),
                    new Point( (int) adjacentTop, newHeight )		
                };
            }
            g.DrawImage(finalBitmap, points);
            imf.SetBitmap(rotatedImage);
            imf.imageFormBindingSource.ResetBindings(false);
        }
    }
}

